#include "crc16.h"
#include <stddef.h> 
// 反转8位数据（用于数据/结果反转配置）
static uint8_t reverse8(uint8_t data) 
{
    uint8_t result = 0;
    for (uint8_t i = 0; i < 8; i++) 
    {
        result <<= 1;
        result |= data & 0x01;
        data >>= 1;
    }
    return result;
}

// 反转16位数据
static uint16_t reverse16(uint16_t data) 
{
    uint16_t result = 0;
    for (uint8_t i = 0; i < 16; i++) {
        result <<= 1;
        result |= data & 0x0001;
        data >>= 1;
    }
    return result;
}

/**
 * @brief  更新CRC16校验值（核心计算函数）
 */
uint16_t CRC16_Update(uint16_t crc, const uint8_t *data, uint32_t len) 
{
    if (data == NULL || len == 0) 
    {
        return crc;
    }

    for (uint32_t i = 0; i < len; i++) 
    {
        uint8_t byte = data[i];
        
        // 若配置数据反转，先反转当前字节
        #if CRC16_REVERSE_DATA
            byte = reverse8(byte);
        #endif

        // 与当前CRC高8位异或
        crc ^= ((uint16_t)byte << 8);

        // 按位处理
        for (uint8_t j = 0; j < 8; j++) 
        {
            if (crc & 0x8000) {  // 最高位为1
                crc = (crc << 1) ^ CRC16_POLYNOMIAL;
            } else {  // 最高位为0
                crc <<= 1;
            }
        }
    }

    return crc;
}

/**
 * @brief  计算CRC16校验值（完整流程）
 */
uint16_t CRC16_Calculate(uint8_t *data, uint32_t len) 
{
    uint16_t crc = CRC16_INIT_VALUE;
    
    // 分块更新CRC
    crc = CRC16_Update(crc, data, len);
    
    // 若配置结果反转，反转最终值
    #if CRC16_REVERSE_RESULT
        crc = reverse16(crc);
    #endif
    
    // 结果异或处理
    return crc ^ CRC16_XOR_OUT;
}

